using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace Etapa1.ComercioEspacial
{
	using ProximityDatabase = Bnoerj.AI.Steering.IProximityDatabase<Bnoerj.AI.Steering.IVehicle>;
	using ProximityToken = Bnoerj.AI.Steering.ITokenForProximityDatabase<Bnoerj.AI.Steering.IVehicle>;
    using PloobsEngine.SceneControl;
    using PloobsEngine;
    using Etapa1.Pedestrian;
    using PloobsEngine.Material;
    using PloobsEngine.Physics.Bepu;
    using PloobsEngine.Modelo;
    using PloobsEngine.Draw;
    using Bnoerj.AI.Steering;
    using Etapa1.Screens;
    
	public class NaveVeiculoPlugIn : PlugIn
	{
        IWorld world;        
        EngineStuff engine;        

        public NaveVeiculoPlugIn(IWorld world, EngineStuff engine)
			: base()
		{            
            crowd = new List<NaveVeiculo>();
            this.world = world;
            this.engine = engine;
		}

		public override String Name { get { return "NavePlugin"; } }

		public override float SelectionOrderSortKey { get { return 0.02f; } }

		public override void Open()
		{
			cyclePD = -1;
			NextPD();
			population = 0;
			
		}

		public override void Update(float currentTime, float elapsedTime)
		{
			for (int i = 0; i < crowd.Count; i++)
			{                
				crowd[i].Update(currentTime, elapsedTime);
			}

            foreach (var item in ComercioEspacialScreen.obstacles)
            {
                Drawing.DrawXZCircle(item.Radius, item.Center, Color.White, 40);
                //   Drawing.DrawXZCircle(item.Radius, item.Center, Color.White, 40);		    
            }
		}


        public void AddAgente(SteerObject modelNave)
		{
			population++;
            NaveVeiculo nv = new NaveVeiculo(pd, null, ComercioEspacialScreen.obstacles);
            nv.Reset();

            modelNave.Vehicle = nv;            
			crowd.Add(nv);

            nv.Position = modelNave.PhysicObject.Position ;

		}
        		
		void NextPD()
		{
			// save pointer to old PD
			ProximityDatabase oldPD = pd;

			// allocate new PD
			const int totalPD = 2;
			switch (cyclePD = (cyclePD + 1) % totalPD)
			{
			case 0:
				{
					Vector3 center = Vector3.Zero;
					float div = 20.0f;
					Vector3 divisions = new Vector3(div, 1.0f, div);
					float diameter = 80.0f; //XXX need better way to get this
					Vector3 dimensions = new Vector3(diameter, diameter, diameter);
					pd = new LocalityQueryProximityDatabase<IVehicle>(center, dimensions, divisions);
					break;
				}
			case 1:
				{
					pd = new BruteForceProximityDatabase<IVehicle>();
					break;
				}
			}
			
			for (int i = 0; i < crowd.Count; i++) crowd[i].NewPD(pd);

			// delete old PD (if any)
			oldPD = null;
		}

		public override List<IVehicle> Vehicles
		{
            get { return crowd.ConvertAll<IVehicle>(delegate(NaveVeiculo p) { return (IVehicle)p; }); }
		}

        public override void Redraw(float currentTime, float elapsedTime)
        {          
        }

        public override void Close()
        {
            
        }
        
        List<NaveVeiculo> crowd;

		// pointer to database used to accelerate proximity queries
		ProximityDatabase pd;

		// keep track of current flock size (inutils !!! :) )
		int population;

		// which of the various proximity databases is currently in use
		int cyclePD;
	}
    
}
